package com.zl.rbac.web.interceptor;

import com.zl.rbac.entity.User;
import com.zl.rbac.exception.NoPermissionException;
import com.zl.rbac.util.RequiredPermission;
import com.zl.rbac.util.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Method;
import java.util.Set;

/**
 * 检查权限的拦截器
 *
 * @ClassName: CheckPermissionInterceptor
 * @author: suke
 * @since: 2021/1/14 9:24
 */
@Component
@Slf4j  // 自动创建一个日志输出对象 log
public class CheckPermissionInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.获取用户信息
        User user = UserContext.getCurrent();
       /*
       //2.判断是否是管理员
        if(user.getAdmin()){
            return true;// 直接放行
        }
        //3.不是管理员, 获取请求方法对象, handler, 把它强转为HandlerMethod, 静态资源通过处理器处理,ResourceHttpRequestHandler
        log.debug(handler.toString());
        if(handler instanceof  HandlerMethod){ //避免出现 ClassCastException
            HandlerMethod handlerMethod =(HandlerMethod) handler; // handlerMethod 对应请求方法对象
            //4.判断该方法是否有@Reqiredpermissioun注解     handlerMethod.getMethod() 获取对应方法的method(反射)对象
            //handlerMethod.getBean()   // Object handlerMethod.getBean() 获取请求方法所在的bean对象
           // Class  handlerMethod.getBeanType() 获取请求方法所在的bean的Class类型
           Method method =  handlerMethod.getMethod();
           if(!method.isAnnotationPresent(RequiredPermission.class)){  //true表示有, false 没有
                return  true;
           }
           //得到方法的表达式  包.类:方法名 Class# getSimpleName() 类名    getName()  全限定名  包.类
            String expression = handlerMethod.getBeanType().getName()+":"+method.getName();
            log.debug(expression);
            //5.判断用户的权限列表是否包含该表达式
           Set<String>  expressionSet =  UserContext.getExpressionInSession();
           if(expressionSet.contains(expression)){  //true 表示包含, 用户用这个权限,
                return true;
           }
        }
        throw  new NoPermissionException("亲,您没有该权限");
        */
        if (!user.getAdmin()) {
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                Method method = handlerMethod.getMethod();
                if (method.isAnnotationPresent(RequiredPermission.class)) {
                    String expression = handlerMethod.getBeanType().getName() + ":" + method.getName();
                    Set<String> expressionSet = UserContext.getExpressionInSession();
                    if (!expressionSet.contains(expression)) {
                        throw new NoPermissionException("亲,您没有该权限");
                    }
                }
            }
        }
        return true;
    }

}
